<template>
  <div id="app">
    <!-- Echarts 图表 -->
    <div ref="ChartRef" class="progressChart"></div>
  </div>
</template>

<script setup>
import * as echarts from 'echarts'
import { ref, onMounted, watch } from 'vue'
const isYear = ref(true)
// const month = ref('')
const ChartRef = ref()
let progressChart
const initChart = () => {
  if (!ChartRef.value) return
  progressChart?.dispose?.()
  progressChart = null
  progressChart = echarts.init(ChartRef.value)
  const option = getOption()
  progressChart.setOption(option)
  // 浏览器窗口大小变化，图表大小自适应
  window.addEventListener('resize', () => {
    progressChart.resize()
  })

  progressChart.on('click', function (params) {
    if (params.componentType === 'xAxis') {
      isYear.value = !isYear.value
      // month.value = params.value
    }
  })
}

const getYAxisData = () => {
  // TODO 按照isYear 区分
  return ['项目一', '项目二', '项目三', '项目四', '项目五', '项目六', '项目七']
}
const yearData = ref({
  planStartTime: ['2021-01-05', '2021-02-01', '2021-03-5', '2021-03-25', '2021-04-01', '2021-04-10', '2021-05-25'],
  planEndTime: ['2021-01-05', '2021-2-8', '2021-03-14', '2021-04-01', '2021-04-10', '2021-05-25', '2021-07-02'],
  actualStartTime: ['2021-01-02', '2021-02-01', '2021-03-5', '2021-03-25', '2021-04-01', '2021-04-10', '2021-05-25'],
  actualEndTime: ['2021-01-05', '2021-02-08', '2021-03-14', '2021-04-01', '2021-04-10', '2021-05-25', '2021-07-25'],
  // planStartTime: [],
  // planEndTime: [],
  // actualStartTime: [],
  // actualEndTime: [],
})
const monthData = ref({
  planStartTime: ['2021-01-05', '2021-01-10', '2021-01-05', '2021-01-02', '2021-01-01', '2021-01-01', '2021-01-25'],
  planEndTime: ['2021-01-05', '2021-01-22', '2021-01-15', '2021-01-22', '2021-01-12', '2021-01-11', '2021-01-26'],
  actualStartTime: ['2021-01-05', '2021-01-10', '2021-01-05', '2021-01-02', '2021-01-01', '2021-01-01', '2021-01-25'],
  actualEndTime: ['2021-01-05', '2021-01-22', '2021-01-15', '2021-01-22', '2021-01-12', '2021-01-11', '2021-01-26'],
})
// 获取计划时间

const getPlanOptions = () => {
  const option = {
    name: '计划时间',
    type: 'bar',
    stack: 'duration',
    zlevel: -1,
  }
  // TODO isYear
  return [
    // 结束时间
    {
      ...option,
      itemStyle: {
        color: '#7ED6F9',
        borderColor: '#fff',
        borderWidth: 1,
      },
      data: isYear.value
        ? yearData.value.planEndTime.map((item) => item + ' 23:59:59')
        : monthData.value.planEndTime.map((item) => item + ' 23:59:59'),
    },
    // 开始时间
    {
      ...option,
      itemStyle: {
        color: '#fff',
      },
      z: 9, // z值小的图形会被z值大的图形覆盖，z相比zlevel优先级更低，而且不会创建新的 Canvas
      data: isYear.value
        ? yearData.value.planStartTime.map((item) => item + ' 00:00:00')
        : monthData.value.planStartTime.map((item) => item + ' 00:00:00'),
    },
  ]
}

// 获取完成时间
const getActualOptions = () => {
  const option = {
    name: '实际完成',
    type: 'bar',
    stack: 'real',
    zlevel: -1,
  }
  // TODO isYear
  return [
    //结束时间
    {
      ...option,
      itemStyle: {
        color: '#FFC04D',
        borderColor: '#fff',
        borderWidth: 1,
      },
      data: isYear.value
        ? yearData.value.actualEndTime.map((item) => item + ' 23:59:59')
        : monthData.value.actualEndTime.map((item) => item + ' 23:59:59'),
    },
    // 开始时间
    {
      ...option,
      itemStyle: {
        color: '#fff',
      },
      z: 9, // z值小的图形会被z值大的图形覆盖，z相比zlevel优先级更低，而且不会创建新的 Canvas
      data: isYear.value
        ? yearData.value.actualStartTime.map((item) => item + ' 00:00:00')
        : monthData.value.actualStartTime.map((item) => item + ' 00:00:00'),
    },
  ]
}
const getOption = () => {
  const allDates = [...yearData.value.actualStartTime, ...yearData.value.actualEndTime].map((item) => item.slice(0, 10))
  const minYear = Math.min(...allDates.map((date) => new Date(date).getFullYear()))
  const xAxisMin = `${minYear}-01-01 00:00:00`

  return {
    // 鼠标移入提示工具
    tooltip: {
      trigger: 'axis',
      formatter(params) {
        if (params[1].data && params[0].data) {
          const name = params[0].name
          // 获取计划时间的 marker 和文本
          const planMarker = params[0].marker
          const planText = params[0].seriesName

          // 获取实际时间的 marker 和文本
          const actualMarker = params[2].marker
          const actualText = params[2].seriesName

          return (
            `${name}<br/>` +
            `${planMarker}${planText}<br/>` +
            `开始时间：${params[1].data.split(' ')[0]}<br/>` +
            `结束时间：${params[0].data.split(' ')[0]}<br/>` +
            `${actualMarker}${actualText}<br/>` +
            `开始时间：${params[3].data.split(' ')[0]}<br/>` +
            `结束时间：${params[2].data.split(' ')[0]}`
          )
        } else {
          return ''
        }
      },
      axisPointer: {
        type: 'shadow',
      },
    },
    grid: {
      containLabel: true,
      show: false,
      right: 80,
      left: 40,
      bottom: 40,
      top: 20,
      backgroundColor: '#fff',
    },
    legend: {
      // 图例组件
      data: ['计划时间', '实际完成'],
      align: 'auto',
      top: 'bottom',
    },
    xAxis: {
      min: xAxisMin,
      triggerEvent: true,
      type: 'time',
      position: 'top', // x 轴位置
      axisTick: {
        // 隐藏刻度
        show: false,
      },
      axisLine: {
        // 隐藏轴线
        show: true,
      },
      splitLine: {
        // 显示网格线
        show: true,
      },
      axisLabel: {
        formatter: {
          month: '{MM}月', // 一月、二月、……
          day: '{dd}日', // 1日、2日、……
        },
        // formatter: function (value) {
        //   const date = new Date(value)
        //   if (isYear.value) {
        //     const month = date.getMonth() + 1
        //     if (date.getDate() === 1) {
        //       return `${month}月`
        //     }
        //     return ''
        //   } else {
        //     const day = date.getDate()
        //     return `${day}日`
        //   }
        // },
      },
    },
    yAxis: {
      inverse: true, // y 轴数据翻转，该操作是为了保证项目一放在最上面，项目七在最下面
      axisTick: {
        // 隐藏刻度
        show: false,
      },
      axisLine: {
        // 隐藏轴线
        show: false,
      },
      data: getYAxisData(),
    },
    series: [...getPlanOptions(), ...getActualOptions()],
  }
}

watch(
  () => isYear.value,
  () => {
    initChart()
  },
)
onMounted(() => {
  initChart()
})
</script>

<style scoped>
#app {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
.progressChart {
  width: 60%;
  height: 420px;
}
</style>
